#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>

static void ShowSigset(sigset_t &set)
{
    for (int signum = 1; signum <= 31; signum++)
    {
        // 如果signum是set的成员，Sigismember()返回1，如果不是成员，返回0，错误时返回-1。在出现错误时，这些函数设置errno来指示原因。
        std::cout << sigismember(&set, signum);
    }
    std::cout << std::endl;
}

static void handler(int signum)
{
    std::cout << " 递达信号: " << signum << std::endl;
}

static void SetBlock(int signum)
{
    sigset_t set;
    sigemptyset(&set);

    sigaddset(&set,signum);

    sigprocmask(SIG_BLOCK,&set,nullptr);
}

// SIGTSTP(20)信号是干嘛的
int main()
{
    
    while(true)
    {
        std::cout<<" pid: "<<getpid()<<std::endl;
        sleep(1);
    }

    return 0;
}

// // 验证是否所有的信号都能被阻塞
// // SIGKILL SIGSTOP
// int main()
// {
//     // 尝试将所有信号阻塞
//     int signum=1;
//     while(signum<=31)
//     {
//         SetBlock(signum);

//         ++signum;
//     }

//     // 打印当前进程的pending信号集
//     while(true)
//     {
//         sigset_t pending;

//         sigpending(&pending);

//         ShowSigset(pending);

//         sleep(1);
//     }

//     return 0;
// }

// // 将某个信号阻塞,不断打印pending信号集,然后突然发送某个信号,观察该信号对应的位置变化
// int main()
// {
//     // 先自定义捕获SIGINT信号
//     signal(SIGINT, handler);

//     // 定义信号集对象
//     sigset_t bset;
//     sigset_t obset;

//     // 初始化信号集
//     sigemptyset(&bset);
//     sigemptyset(&obset);

//     // 添加要屏蔽的信号
//     sigaddset(&bset, SIGINT);

//     // 设置PCB中的block信号集
//     // int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
//     sigprocmask(SIG_BLOCK, &bset, &obset);

//     int size = 0;

//     // 打印PCB中的pending信号集
//     while (true)
//     {
//         sigset_t pending;
//         sigemptyset(&pending);
//         // 获取当前进程的pending信号集
//         sigpending(&pending);
//         ShowSigset(pending);

//         sleep(1);
//         size++;
//         // 30s过后取消对SIGINT的阻塞
//         if (size == 30)
//         {
//             // 默认情况下，恢复对于2号信号的block的时候，确实会进行递达
//             // 但是2号信号的默认处理动作是终止进程！
//             // 需要对2号信号进行捕捉
//             std::cout << "解除对于SIGINT号信号的block" << std::endl;
//             int n = sigprocmask(SIG_SETMASK, &obset, nullptr);
//             // sigprocmask(SIG_UNBLOCK,&bset,&obset);

//             assert(n == 0);
//             (void)n;

//         }
//     }

//     return 0;
// }

// // 验证是否所有信号都能被自定义捕获
// // 不是所有信号都能被自定义捕获,若SIGKIll SIGSTOP
// int main()
// {
//     for(int signum=1;signum<=31;signum++)
//     {
//         signal(signum,handler);
//     }

//     while(true)
//     {

//     }

//     return 0;
// }

// 了解信号集signal_t及其操作函数
// int main()
// {
//     sigset_t set;

//     //sigemptyset(&set);
//     sigfillset(&set);
//     for(int signum=1;signum<=31;signum++)
//     {
//         //sigaddset(&set,signum);
//         sigdelset(&set,signum);
//         ShowSigset(set);
//     }

//     // // int sigfillset(sigset_t *set);
//     // // Sigfillset()初始化添加set中所有的信号存在。
//     // sigfillset(&set);

//     // // int sigemptyset(sigset_t *set);
//     // //  Sigemptyset()将set给出的信号集初始化为空，并将所有信号从集合中排除。
//     // sigemptyset(&set);

//     // // int sigaddset(sigset_t *set, int signum);
//     // // int sigdelset(sigset_t *set, int signum);
//     // // Sigaddset()和sigdelset()分别从set中添加和删除信号signum。
//     // sigaddset(&set, SIGINT);

//     // // int sigismember(const sigset_t *set, int signum);
//     // // Sigismember()测试signum是否是set的成员。
//     // for (int signum = 1; signum <= 31; signum++)
//     // {
//     //     std::cout << sigismember(&set, signum);
//     // }
//     // std::cout << std::endl;

//     // sigdelset(&set,SIGINT);

//     // for (int signum = 1; signum <= 31; signum++)
//     // {
//     //     std::cout << sigismember(&set, signum);
//     // }
//     // std::cout << std::endl;

//     return 0;
// }